package com.soriya.switcher

import android.content.Context
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.view.Surface
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.View
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.camera.view.PreviewView
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.PrimaryTabRow
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SecondaryTabRow
import androidx.compose.material3.Slider
import androidx.compose.material3.SliderDefaults
import androidx.compose.material3.Tab
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.blankj.utilcode.util.AppUtils
import com.developer.filepicker.model.DialogConfigs
import com.developer.filepicker.model.DialogProperties
import com.developer.filepicker.view.FilePickerDialog
import com.soriya.switcher.component.CameraPreview
import com.soriya.switcher.component.LargeText
import com.soriya.switcher.component.MediumText
import com.soriya.switcher.component.SmallText
import com.soriya.switcher.component.SmallerText
import com.soriya.switcher.component.VerySmallerText
import com.soriya.switcher.component.VerySmallerTextButton
import com.soriya.switcher.config.CameraConfig
import com.soriya.switcher.config.ConfigRepository
import com.soriya.switcher.core.VideoDecoder
import com.soriya.switcher.ui.theme.Primary
import com.soriya.switcher.ui.theme.SwitcherTheme
import com.soriya.switcher.util.PermissionUtils
import com.soriya.switcher.util.showToast
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

private const val TAG = "MainActivity"

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            SwitcherTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    Box(
                        Modifier
                            .padding(innerPadding)
                    ) {
                        Page()
                    }
                }
            }
        }
        Log.i(TAG, "smallestScreenWidthDp: ${resources.configuration.smallestScreenWidthDp}")
    }
}

//@Preview(showBackground = true, widthDp = 1080, heightDp = 1920)
@Composable
fun Page() {
    Column(
        Modifier.padding(
            dimensionResource(com.soriya.common.R.dimen.xdp_30),
            dimensionResource(com.soriya.common.R.dimen.xdp_26)
        )
    ) {
        Header()
        Spacer(modifier = Modifier.height(dimensionResource(com.soriya.common.R.dimen.xdp_25)))
        Main()
        Spacer(modifier = Modifier.height(dimensionResource(com.soriya.common.R.dimen.xdp_25)))
        Footer()
    }
}

@Composable
fun Header(modifier: Modifier = Modifier) {
    Row(
        modifier = modifier.fillMaxWidth()
    ) {
        Image(
            painter = painterResource(id = R.mipmap.logo),
            contentDescription = null,
            modifier = Modifier.height(dimensionResource(com.soriya.common.R.dimen.xdp_36))
        )
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Main(modifier: Modifier = Modifier) {
    Row(
        horizontalArrangement = Arrangement.spacedBy(dimensionResource(com.soriya.common.R.dimen.xdp_24)),
        modifier = modifier.fillMaxWidth()
    ) {
        var videoSurface by remember { mutableStateOf<Surface?>(null) }

        val camera = true
        if (camera) {
            CameraPreview(
                modifier = Modifier
                    .size(
                        dimensionResource(com.soriya.common.R.dimen.xdp_600),
                        dimensionResource(com.soriya.common.R.dimen.xdp_1066)
                    )
            )
        } else {
            AndroidView(
                modifier = Modifier
                    .size(
                        dimensionResource(com.soriya.common.R.dimen.xdp_600),
                        dimensionResource(com.soriya.common.R.dimen.xdp_1066)
                    ),
                factory = { context ->
                    SurfaceView(context).apply {
                        holder.addCallback(object : SurfaceHolder.Callback {
                            override fun surfaceChanged(
                                holder: SurfaceHolder,
                                format: Int,
                                width: Int,
                                height: Int
                            ) {}

                            override fun surfaceCreated(holder: SurfaceHolder) {
                                videoSurface = holder.surface
                            }

                            override fun surfaceDestroyed(holder: SurfaceHolder) {
                            }
                        })
                    }
                },
                update = {}
            )
        }

        Column {
            val tabList = listOf("控制", "组件", "推流", "图层")
            val pageState = rememberPagerState { tabList.size }
            val scope = rememberCoroutineScope()
            SecondaryTabRow(
                selectedTabIndex = pageState.currentPage
            ) {
                tabList.forEachIndexed { index, title ->
                    Tab(
                        selected = index == pageState.currentPage,
                        onClick = {
                            scope.launch {
                                pageState.scrollToPage(index, 0F)
                            }
                        },
                        text = { LargeText(text = title) },
                        modifier = Modifier
                            .height(dimensionResource(com.soriya.common.R.dimen.xdp_60))
                    )
                }
            }
            HorizontalPager(
                state = pageState,
            ) { page ->
                if (page == 0) {
                    MainControl(videoSurface)
                } else if (page == 1) {
                    MainComponent()
                }
            }
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Preview(showBackground = true)
@Composable
fun MainControl(surface: Surface? = null) {
    val scope = rememberCoroutineScope()

    val context = LocalContext.current
    val configRepository = remember { ConfigRepository(context) }
    val config by configRepository.config.collectAsStateWithLifecycle(initialValue = CameraConfig())

    val dialogProperties = remember {
        DialogProperties().apply {
            selection_mode = DialogConfigs.SINGLE_MODE
            selection_type = DialogConfigs.FILE_SELECT
            root = Environment.getExternalStorageDirectory()
            extensions = null
            show_hidden_files = true
        }
    }

    val filePickerDialog = remember {
        FilePickerDialog(context, dialogProperties).apply {
            setDialogSelectionListener {
                Log.i(TAG, "MainControl: ${it.contentToString()}")
                scope.launch(Dispatchers.IO) {
                    configRepository.updateConfig { copy(videoPath = it[0]) }
                }
            }
        }
    }

    var audioVolume by remember { mutableStateOf(0F) }

    val videoDecoder = remember { VideoDecoder(context) }
    videoDecoder.setOnVolumeListener { volume ->
        audioVolume = volume
    }

    var isStartCamera by remember { mutableStateOf(videoDecoder.started()) }

    // 虚拟摄像头
    Column {
        Column(
            modifier = Modifier
                .background(Color(0xFF25272D))
                .padding(
                    dimensionResource(com.soriya.common.R.dimen.xdp_20),
                    dimensionResource(com.soriya.common.R.dimen.xdp_18)
                )
        ) {
            Row {
                MediumText(text = "相机输入")
            }
            Spacer(modifier = Modifier.height(dimensionResource(com.soriya.common.R.dimen.xdp_18)))
            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(1.dp)
                    .background(Color(0x66FFFFFF))
            )
            Row(
                horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically,
                modifier = Modifier
                    .padding(top = dimensionResource(com.soriya.common.R.dimen.xdp_24))
                    .fillMaxWidth()
            ) {
                MediumText(text = "输入源", modifier = Modifier.width(dimensionResource(com.soriya.common.R.dimen.xdp_90)))
                VerySmallerTextButton(
                    text = "选择",
                    onClick = {
                        if (!PermissionUtils.checkStoragePermission(context)) return@VerySmallerTextButton
                        filePickerDialog.show()
                    },
                    shape = RoundedCornerShape(dimensionResource(com.soriya.common.R.dimen.xdp_6))
                )
            }
            if (config.videoPath.isNotBlank()) {
                SmallText(text = config.videoPath)
            }
            Row(
                verticalAlignment = Alignment.CenterVertically,
                modifier = Modifier.padding(top = dimensionResource(com.soriya.common.R.dimen.xdp_24))
            ) {
                MediumText(text = "旋转角度", modifier = Modifier.width(dimensionResource(com.soriya.common.R.dimen.xdp_90)))
                Row(
                    horizontalArrangement = Arrangement.SpaceBetween,
                    modifier = Modifier.fillMaxWidth()
                ) {
                    VerySmallerTextButton(
                        text = "0°",
                        onClick = {
                            if (config.rotate == CameraConfig.ROTATE_0) return@VerySmallerTextButton
                            scope.launch(Dispatchers.IO) {
                                configRepository.updateConfig { copy(rotate = CameraConfig.ROTATE_0) }
                            }
                        },
                        border = if (config.rotate == CameraConfig.ROTATE_0) BorderStroke(dimensionResource(com.soriya.common.R.dimen.xdp_2), Primary) else null,
                        shape = RoundedCornerShape(dimensionResource(com.soriya.common.R.dimen.xdp_6)),
                        paddingValues = PaddingValues(
                            dimensionResource(com.soriya.common.R.dimen.xdp_16),
                            dimensionResource(com.soriya.common.R.dimen.xdp_8)
                        )
                    )
                    VerySmallerTextButton(
                        text = "90°",
                        onClick = {
                            if (config.rotate == CameraConfig.ROTATE_90) return@VerySmallerTextButton
                            scope.launch(Dispatchers.IO) {
                                configRepository.updateConfig { copy(rotate = CameraConfig.ROTATE_90) }
                            }
                        },
                        border = if (config.rotate == CameraConfig.ROTATE_90) BorderStroke(dimensionResource(com.soriya.common.R.dimen.xdp_2), Primary) else null,
                        shape = RoundedCornerShape(dimensionResource(com.soriya.common.R.dimen.xdp_6)),
                        paddingValues = PaddingValues(
                            dimensionResource(com.soriya.common.R.dimen.xdp_16),
                            dimensionResource(com.soriya.common.R.dimen.xdp_8)
                        )
                    )
                    VerySmallerTextButton(
                        text = "180°",
                        onClick = {
                            if (config.rotate == CameraConfig.ROTATE_180) return@VerySmallerTextButton
                            scope.launch(Dispatchers.IO) {
                                configRepository.updateConfig { copy(rotate = CameraConfig.ROTATE_180) }
                            }
                        },
                        border = if (config.rotate == CameraConfig.ROTATE_180) BorderStroke(dimensionResource(com.soriya.common.R.dimen.xdp_2), Primary) else null,
                        shape = RoundedCornerShape(dimensionResource(com.soriya.common.R.dimen.xdp_6)),
                        paddingValues = PaddingValues(
                            dimensionResource(com.soriya.common.R.dimen.xdp_16),
                            dimensionResource(com.soriya.common.R.dimen.xdp_8)
                        )
                    )
                    VerySmallerTextButton(
                        text = "270°",
                        onClick = {
                            if (config.rotate == CameraConfig.ROTATE_270) return@VerySmallerTextButton
                            scope.launch(Dispatchers.IO) {
                                configRepository.updateConfig { copy(rotate = CameraConfig.ROTATE_270) }
                            }
                        },
                        border = if (config.rotate == CameraConfig.ROTATE_270) BorderStroke(dimensionResource(com.soriya.common.R.dimen.xdp_2), Primary) else null,
                        shape = RoundedCornerShape(dimensionResource(com.soriya.common.R.dimen.xdp_6)),
                        paddingValues = PaddingValues(
                            dimensionResource(com.soriya.common.R.dimen.xdp_16),
                            dimensionResource(com.soriya.common.R.dimen.xdp_8)
                        )
                    )
                }
            }
            VerySmallerTextButton(
                text = "重新播放",
                onClick = {},
                shape = RoundedCornerShape(percent = 50),
                border = BorderStroke(dimensionResource(com.soriya.common.R.dimen.xdp_2), Primary),
                paddingValues = PaddingValues(
                    dimensionResource(com.soriya.common.R.dimen.xdp_24),
                    dimensionResource(com.soriya.common.R.dimen.xdp_12)
                ),
                modifier = Modifier
                    .padding(top = dimensionResource(com.soriya.common.R.dimen.xdp_24))
            )
        }
        // 虚拟麦克风
        Column(
            modifier = Modifier
                .padding(top = 2.dp)
                .background(Color(0xFF25272D))
                .padding(
                    dimensionResource(com.soriya.common.R.dimen.xdp_20),
                    dimensionResource(com.soriya.common.R.dimen.xdp_18)
                )
        ) {
            Row {
                MediumText(text = "声音输入")
            }
            Spacer(modifier = Modifier.height(dimensionResource(com.soriya.common.R.dimen.xdp_18)))
            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(1.dp)
                    .background(Color(0x66FFFFFF))
            )
            Row(
                verticalAlignment = Alignment.CenterVertically,
                modifier = Modifier.padding(top = dimensionResource(com.soriya.common.R.dimen.xdp_24))
            ) {
                MediumText(text = "音量", modifier = Modifier.width(dimensionResource(com.soriya.common.R.dimen.xdp_70)))
                LinearProgressIndicator(
                    progress = { audioVolume },
                    modifier = Modifier.fillMaxWidth()
                )
            }
            Row(
                verticalAlignment = Alignment.CenterVertically,
                modifier = Modifier.padding(top = dimensionResource(com.soriya.common.R.dimen.xdp_24))
            ) {
                MediumText(text = "输出", modifier = Modifier.width(dimensionResource(com.soriya.common.R.dimen.xdp_70)))
                Slider(
                    value = config.audioOutputVolume,
                    onValueChange = {
                        Log.d(TAG, "MainControl: $it")
                        scope.launch(Dispatchers.IO) {
                            configRepository.updateConfig { copy(audioOutputVolume = it) }
                        }
                    },
                    thumb = {
                        SliderDefaults.Thumb(
                            interactionSource = remember { MutableInteractionSource() },
                            modifier = Modifier.height(dimensionResource(com.soriya.common.R.dimen.xdp_28))
                        )
                    },
                    track = { sliderState ->
                        SliderDefaults.Track(
                            sliderState = sliderState,
                            modifier = Modifier.height(dimensionResource(com.soriya.common.R.dimen.xdp_6))
                        )
                    },
                    modifier = Modifier
                        .fillMaxWidth()
                )
            }
            Row(
                verticalAlignment = Alignment.CenterVertically,
                modifier = Modifier.padding(top = dimensionResource(com.soriya.common.R.dimen.xdp_24))
            ) {
                MediumText(text = "模式", modifier = Modifier.width(dimensionResource(com.soriya.common.R.dimen.xdp_70)))
                Row(
                    horizontalArrangement = Arrangement.SpaceBetween,
                    modifier = Modifier.fillMaxWidth()
                ) {
                    VerySmallerTextButton(
                        text = "监听并输出",
                        onClick = {
                            if (config.audioMode == 0) return@VerySmallerTextButton
                            scope.launch(Dispatchers.IO) {
                                configRepository.updateConfig { copy(audioMode = 0) }
                            }
                        },
                        shape = RoundedCornerShape(dimensionResource(com.soriya.common.R.dimen.xdp_6)),
                        border = if (config.audioMode == 0) BorderStroke(dimensionResource(com.soriya.common.R.dimen.xdp_2), Primary) else null,
                    )
                    VerySmallerTextButton(
                        text = "仅监听",
                        onClick = {
                            if (config.audioMode == 1) return@VerySmallerTextButton
                            scope.launch(Dispatchers.IO) {
                                configRepository.updateConfig { copy(audioMode = 1) }
                            }
                        },
                        shape = RoundedCornerShape(dimensionResource(com.soriya.common.R.dimen.xdp_6)),
                        border = if (config.audioMode == 1) BorderStroke(dimensionResource(com.soriya.common.R.dimen.xdp_2), Primary) else null,
                    )
                    VerySmallerTextButton(
                        text = "关闭监听",
                        onClick = {
                            if (config.audioMode == 2) return@VerySmallerTextButton
                            scope.launch(Dispatchers.IO) {
                                configRepository.updateConfig { copy(audioMode = 2) }
                            }
                        },
                        shape = RoundedCornerShape(dimensionResource(com.soriya.common.R.dimen.xdp_6)),
                        border = if (config.audioMode == 2) BorderStroke(dimensionResource(com.soriya.common.R.dimen.xdp_2), Primary) else null,
                    )
                }
            }
        }
        // App列表
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 2.dp)
                .background(Color(0xFF25272D))
                .padding(
                    dimensionResource(com.soriya.common.R.dimen.xdp_20),
                    dimensionResource(com.soriya.common.R.dimen.xdp_18)
                )
        ) {
            Image(
                painter = painterResource(R.mipmap.ic_xhs),
                contentDescription = null,
                modifier = Modifier
                    .size(dimensionResource(com.soriya.common.R.dimen.xdp_120))
                    .clip(RoundedCornerShape(8.dp))
                    .clickable(onClick = {
                        if (AppUtils.isAppInstalled("com.xingin.xhs")) {
                            AppUtils.launchApp("com.xingin.xhs")
                        } else {
                            showToast("未安装小红书App")
                        }
                    })
            )

            Spacer(modifier = Modifier.width(dimensionResource(com.soriya.common.R.dimen.xdp_20)))

            IconButton(
                onClick = {},
                colors = IconButtonDefaults.iconButtonColors(containerColor = Color(0xFF11111C), contentColor = Primary),
                modifier = Modifier
                    .size(dimensionResource(com.soriya.common.R.dimen.xdp_54))
                    .clip(RoundedCornerShape(2.dp))
            ) {
                Icon(imageVector = Icons.Default.Add, contentDescription = null)
            }
        }
        //
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 2.dp)
                .clip(
                    RoundedCornerShape(
                        0.dp,
                        0.dp,
                        dimensionResource(com.soriya.common.R.dimen.xdp_10),
                        dimensionResource(com.soriya.common.R.dimen.xdp_10)
                    )
                )
                .background(Color(0xFF25272D))
                .padding(
                    dimensionResource(com.soriya.common.R.dimen.xdp_20),
                    dimensionResource(com.soriya.common.R.dimen.xdp_18)
                )
        ) {
            Button(
                onClick = {
                    if (config.videoPath.isBlank()) {
                        showToast("请选择输入源")
                        return@Button
                    }
                    if (videoDecoder.started()) {
                        videoDecoder.stop()
                    } else {
                        Log.i(TAG, "surface: $surface")
                        videoDecoder.start(
                            videoPath = config.videoPath,
                            rotate = config.rotate,
                            surface = surface)
                    }
                    isStartCamera = videoDecoder.started()
                },
                shape = RoundedCornerShape(dimensionResource(com.soriya.common.R.dimen.xdp_4)),
                border = BorderStroke(dimensionResource(com.soriya.common.R.dimen.xdp_2), Primary),
                colors = ButtonDefaults.buttonColors(containerColor = Primary, contentColor = Color(0xFF333333)),
                modifier = Modifier
            ) {
                if (isStartCamera) {
                    VerySmallerText(text = "停止相机")
                } else {
                    VerySmallerText(text = "启动相机")
                }
            }
        }
    }
}

@Composable
fun MainComponent() {}


@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Footer() {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .fillMaxHeight()
            .background(Color(0xFF25272D))
            .padding(
                dimensionResource(com.soriya.common.R.dimen.xdp_20),
                dimensionResource(com.soriya.common.R.dimen.xdp_18)
            )
    ) {
        val tabList = listOf("视频去重", "音频去重")
        val pageState = rememberPagerState { tabList.size }
        val scope = rememberCoroutineScope()
        PrimaryTabRow(
            selectedTabIndex = pageState.currentPage,
            containerColor = Color.Transparent
        ) {
            tabList.forEachIndexed { index, title ->
                Tab(
                    selected = index == pageState.currentPage,
                    onClick = {
                        scope.launch {
                            pageState.scrollToPage(index, 0F)
                        }
                    },
                    text = { LargeText(text = title) },
                    modifier = Modifier
                        .height(dimensionResource(com.soriya.common.R.dimen.xdp_60))
                )
            }
        }
    }
}